package controller

import (
	"fmt"
	"illuminant/config"
	"illuminant/logger"
	"illuminant/middleware/auth"
	"illuminant/util"
	"strings"

	"github.com/gin-gonic/gin"

	"github.com/casbin/casbin/v2"
	"github.com/casbin/casbin/v2/model"
)

func getEnforcer() *casbin.Enforcer {
	lg := logger.GetLogger()
	cnf := config.Get()

	adp, err := auth.NewAdapter()
	if err != nil {
		lg.Err(err).Msg("casbin adapter error")
		panic(err)
	}

	m, err := model.NewModelFromString(cnf.Auth.RBACModel)
	if err != nil {
		lg.Err(err).Msg("casbin model from string error")
		panic(err)
	}

	e, err := casbin.NewEnforcer(m, adp)
	if err != nil {
		lg.Err(err).Msg("casbin enforcer error")
		panic(err)
	}

	return e
}

func GetRolePermissions(c *gin.Context) {
	e := getEnforcer()

	rules := e.GetPermissionsForUser(c.Param("role"))
	lines := make([]string, 0)
	for _, rule := range rules {
		lines = append(lines, strings.Join(append([]string{"p"}, rule...), ","))
	}

	util.Success(c, "", lines)
}

func AddRolePermission(c *gin.Context) {
	var (
		param struct {
			Role string `json:"role"`
			Obj  string `json:"obj"`
			Act  string `json:"act"`
		}
		ret bool
		err error
	)

	if err = c.BindJSON(&param); err != nil {
		util.Fail(c, util.REQUEST_PARAM_ERROR, err.Error(), nil)
		return
	}

	e := getEnforcer()

	if param.Act == "" {
		param.Act = "*"
	}
	ret, err = e.AddPermissionForUser(param.Role, param.Obj, param.Act)
	if err != nil {
		util.Fail(c, util.DATA_INSERT_ERROR, fmt.Sprintf("创建权限(p, %s, %s, %s)失败", param.Role, param.Obj, param.Act), nil)
		return
	}

	if ret {
		util.Success(c, fmt.Sprintf("创建权限(p, %s, %s, %s)成功", param.Role, param.Obj, param.Act), nil)
	} else {
		util.Success(c, fmt.Sprintf("权限(p, %s, %s, %s)已经存在", param.Role, param.Obj, param.Act), nil)
	}
}

func DeleteRolePermission(c *gin.Context) {
	var (
		param struct {
			Role string `json:"role"`
			Obj  string `json:"obj"`
			Act  string `json:"act"`
		}
		ret bool
		err error
	)

	if err = c.BindJSON(&param); err != nil {
		util.Fail(c, util.REQUEST_PARAM_ERROR, err.Error(), nil)
		return
	}

	e := getEnforcer()

	if param.Act == "" {
		param.Act = "*"
	}
	ret, err = e.DeletePermissionForUser(param.Role, param.Obj, param.Act)
	if err != nil {
		util.Fail(c, util.DATA_INSERT_ERROR, fmt.Sprintf("删除权限(p, %s, %s, %s)失败", param.Role, param.Obj, param.Act), nil)
		return
	}

	if ret {
		util.Success(c, fmt.Sprintf("删除权限(p, %s, %s, %s)成功", param.Role, param.Obj, param.Act), nil)
	} else {
		util.Success(c, fmt.Sprintf("权限(p, %s, %s, %s)不存在", param.Role, param.Obj, param.Act), nil)
	}
}

func AddRolesForUser(c *gin.Context) {
	var (
		param struct {
			User  string   `json:"user"`
			Roles []string `json:"roles"`
		}
		ret bool
		err error
	)

	if err = c.BindJSON(&param); err != nil {
		util.Fail(c, util.REQUEST_PARAM_ERROR, err.Error(), nil)
		return
	}

	e := getEnforcer()

	ret, err = e.AddRolesForUser(param.User, param.Roles)
	if err != nil {
		util.Fail(c, util.DATA_INSERT_ERROR, fmt.Sprintf("关联用户(%s)和角色失败", param.User), nil)
		return
	}

	if ret {
		util.Success(c, fmt.Sprintf("关联用户(%s)和角色成功", param.User), nil)
	} else {
		util.Success(c, fmt.Sprintf("用户(%s)和角色已经关联", param.User), nil)
	}

}

func DeleteRoleForUser(c *gin.Context) {
	var (
		param struct {
			User string `json:"user"`
			Role string `json:"role"`
		}
		ret bool
		err error
	)

	if err = c.BindJSON(&param); err != nil {
		util.Fail(c, util.REQUEST_PARAM_ERROR, err.Error(), nil)
		return
	}

	e := getEnforcer()

	ret, err = e.DeleteRoleForUser(param.User, param.Role)
	if err != nil {
		util.Fail(c, util.DATA_INSERT_ERROR, fmt.Sprintf("删除用户(%s)的角色(%s)失败", param.User, param.Role), nil)
		return
	}

	if ret {
		util.Success(c, fmt.Sprintf("删除用户(%s)的角色(%s)成功", param.User, param.Role), nil)
	} else {
		util.Success(c, fmt.Sprintf("用户(%s)不属于角色(%s)", param.User, param.Role), nil)
	}
}

func DeleteRolesForUser(c *gin.Context) {
	var (
		param struct {
			User string `json:"user"`
		}
		ret bool
		err error
	)

	if err = c.BindJSON(&param); err != nil {
		util.Fail(c, util.REQUEST_PARAM_ERROR, err.Error(), nil)
		return
	}

	e := getEnforcer()

	ret, err = e.DeleteRolesForUser(param.User)
	if err != nil {
		util.Fail(c, util.DATA_INSERT_ERROR, fmt.Sprintf("删除用户(%s)的角色失败", param.User), nil)
		return
	}

	if ret {
		util.Success(c, fmt.Sprintf("删除用户(%s)的角色成功", param.User), nil)
	} else {
		util.Success(c, fmt.Sprintf("用户(%s)没有角色信息", param.User), nil)
	}
}
